package com.study.java8.char08;

// reuse/Beetle.java
// The full process of initialization
class Insect {
    private int i = 9;
    protected int j;

    Insect() {
        System.out.println("i = " + i + ", j = " + j);
        j = 39;
    }

    private static int x1 = printInit("static Insect.x1 initialized");

    static int printInit(String s) {
        System.out.println(s);
        return 47;
    }
}

public class Beetle extends Insect {
    private int k = printInit("Beetle.k.initialized");

    public Beetle() {
        System.out.println("k = " + k);
        System.out.println("j = " + j);
    }

    private static int x2 = printInit("static Beetle.x2 initialized");

    public static void main(String[] args) {
        System.out.println("Beetle constructor");
        Beetle b = new Beetle();
    }
}

/*
* 继承和初始化
* 当执行java Beetle，首先会试图访问Beetle类的`mian()` 方法(一个静态方法)，加载器启动并找出Beetle类的编译代码(在名为Beetle.class的文件中)。加载过程中，编译器注意到有个基类，于是继续加载基类。不论是否创建基类的对象，基类都会和被加载。

如果基类还存在自身的基类，那么第二个基类也将被加载，依次类推。接下来，根基类(Insect) 的static 的初始化开始执行，接着是派生类。(派生类中的static的初始化可能依赖基类成员是否被正确地初始化)。

至此，必要的类都加载完毕，可以创建对象了。首先，对象中的所有基本变量都被置为默认值，对象引用被设定为null——这是通过将对象内存设为二进制零值一举生成的。接着会调用基类的构造器。基类构造器和派生类构造器一样以相同的顺序经历相同的过程。当基类构造器完成后，实例变量按照文本顺序初始化，最终，构造器的剩余部分被执行。
*
* */


/*
static Insect.x1 initialized
static Beetle.x2 initialized
Beetle constructor
i = 9, j = 0
Beetle.k.initialized
k = 47
j = 39*/
